In LLVM, how do I reflect metadata in the assembly file? - metadata

Here's the setup: I'm working with LLVM and I have an analysis pass that needs to make some results of the analysis available for later use. These results need to be visible in the final .s file (ARM architecture) that I generate. I then run some scripts on the .s file that do further analysis that use these results but is also dependent on the actual structure of the ASM generated (otherwise I would just use more LLVM passes).
Originally I thought metadata was what I wanted, and I created some simple test function to insert some metadata for each instruction I care about. But I don't know how to make this metadata reflected in the final .s file. Even worse, I cannot figure out how to make the metadata string what I actually want. The "5" you'll see below is never output. Instead I see 46 or 47 in the output.
void addMetadata(Instruction& I) {
LLVMContext& C = I.getContext();
MDNode* N = MDNode::get(C, MDString::get(C, "5"));
I.setMetadata("alias_set", N);
std::cerr << "Instruction" << std::endl;
I.dump();
}
Example output:
Instruction
%30 = load i32* %29, align 4, !dbg !67, !alias_set !46
I've also heard the inline assembly might work, but I don't know if that would allow me to insert comments or labels before a specific IR instruction. If the IR is reordered, then that label or comment would need to follow it wherever it goes. Basically, I just want to see a label or a comment in the .s file with some small amount of information that I want. Does anyone know how to do that? Thanks!

On further research, I have found out that you just can't easily do what I'm trying to do with metadata. Debug info is a special case of metadata that is output to assembly files. It turns out that what worked for me was inlining ASM. This would probably be a helpful thing to include as part of the LLVM Metadata class; the ability to dump metadata. What I ended up doing is extracting any metadata I care about and inserting it as inline assembly in front of the instruction. This function will insert assembly comments in front of an instruction, and you can replace #info_you_want_to_output with the string representation of whatever data you care about. Note: # is generally the start of a comment for ARM assembly. This function uses ATT assembly syntax, but you can replace AD_ATT with AD_Intel if you need Intel syntax.
void insertInfo(Instruction& I)
{
std::vector<llvm::Type *> AsmArgTypes = {};
FunctionType *AsmFTy = FunctionType::get(Type::getVoidTy(I.getContext()), AsmArgTypes, false);
InlineAsm *IA = InlineAsm::get(AsmFTy, std::string("#info_you_want_to_output"), "",
/*hasSideEffects*/ true, /*isAlignStack*/ false, InlineAsm::AD_ATT);
Instruction *newInst = CallInst::Create(IA, "", &I);
}
This is some example output in my ARM assembly (.s) file:
ldr r2, .LCPI0_2
mov r1, r4
#APP
##info_you_want_to_output
#NO_APP
bl __cxa_atexit
pop {r4, lr}
mov pc, lr
Note that before and after the inline assembly, it inserts #APP and #NO_APP. I'm not sure what this indicates, but it's easy to ignore. Hope this helps anyone in the future.

Related

How to access the child nodes in a device tree (DTS) in Zephyr using DT_FOREACH_CHILD

I'm developing an application for an nRF52 SoC to access some external devices, kind of detectors in this case, so I have defined a custom format (and its corresponding yaml file) for my device access description node. It is kind of:
n: detectors {
compatible = "foo-detectors";
// Definition of first channel
det0: det_0 {
irq-pins = <13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "Bar detector channel 1";
};
// Definition of second channel
det1: det_1 {
irq-pins = <17 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "Bar detector channel 2";
};
};
Suppose I have a structure definition for holding data about the pins to which those devices are physically connected, say:
struct foo_detector_desc {
int irqpin;
int irqpin_flags;
}
Using Zephyr macros, I can use from my code the individual values for those nodes. For instance, DT_PROP_BY_IDX(DT_NODELABEL(det0), irq_pins, 0) expands to 13, DT_PROP_BY_IDX(DT_NODELABEL(det0), irq_pins, 1) expands to the value of OR'ed flags GPIO_PULL_UP | GPIO_ACTIVE_LOW.
But I don't want to create a ten-page code full of conditionals in the form DT_NODE_EXISTS(DT_ALIAS(det#)), but something more compact, flexible and maintainable.
I came across Zephyr macro DT_FOREACH_CHILD that is intended for being used in that scenario with which I can create a list with the labels, as showcased in the example embedded in the documentation:
#define LABEL_AND_COMMA(node_id) DT_LABEL(node_id),
const char *child_labels[] = {
DT_FOREACH_CHILD(DT_NODELABEL(n), LABEL_AND_COMMA)
};
Trying to use that for filling a static structures array, I tried following code but, yet it expands to two elements in the array, the structure fields are not initialised with desired values.
#define PIN_INFO_AND_COMMA(node_id) \
{ \
.pin=DT_PROP_BY_IDX(node_id, irq_pins, 0),\
.flags=DT_PROP_BY_IDX(node_id, irq_pins, 1),\
},
const struct detector_data _det_data[] = {
DT_FOREACH_CHILD(DT_NODELABEL(n), PIN_INFO_AND_COMMA)
};
I'm using Visual Studio Code with the nRF Connect plugin.
Is there a way to generate/see how those macros expand when compiled?
What is the correct way for initialising the structure fields (pins, flags)?
BR
It is possible to expand the macros one level at a time in VS Code. It is needed to click over the macro, then select it by double-clicking on it, and a bulb light will, eventually, show up. The option Insert Macro will replace the macro with its expansion.
Regarding using the DTS in code, the code I wrote in my previous post is OK, but I think I found a bug in the debugger. If I don't include any code using the value of _det_data, the debugger doesn't say the constant was optimised-out and displays wrong values when inspecting its content. That made me waste a lot of time.
For anyone interested on using DTS files for nRF devices in Zephyr, I posted all details in a thread in Nordic's developers forum (here).
BR

Check if a command exists using qmake

I am working on a project which incorporates C code, as well as (MASM-like) assembly. I want to be able to compile it on Linux, as well as Windows, thus I am using a third-party assembler (jwasm) as follows:
QMAKE_PRE_LINK += jwasm -coff -Fo$$assembly_obj $$PWD/assembly.asm
(here, assembly_obj holds the directory I want jwasm to save the output. Oh, by the way: when using jwasm it is critical to first specify all the parameters, and only at the end the input files, otherwise it will ignore the parameters)
To make it easier for other people to compile the project, I would like to be able to check if jwasm is in their path, and if not, emit an error() telling them how to fix this. However, I am not sure if this is even possible using qmake. I have tried:
exists("jwasm") { # Always false
message("jwasm found!")
}
as well as:
packagesExist(jwasm) { # Always true
message("jwasm found!")
}
I have looked around in the qmake docs, but couldn't find any other alternatives...

NUnit long string gets truncated

I am using NUnit to write a test for a class that knows how to serialize itself to XML. The class has lots of properties so the XML fragment produced by the function I'm testing might be very long even with the default state of a new object.
When I run the test in the NUnit test runner and I've purposefully broken the expected returned XML, the test runner only shows a truncated version of the expected and actual string returned from the function that serializes the object to XML. Such as:
MyProject.MyTests.CanCreateObjectAndEdit:
Expected string length 525 but was 1485. Strings differ at index 509.
Expected: "...ffer="False" IsThing="False" /></MyObject>"
But was: "...ffer="False" IsThing="False" /><MySubObject ItemID="60..."
--------------------------------------------^
Is there any way to get NUnit to return the entire expected and actual string? I have NUnit 2.6.3 (the latest release) and I am using the NUnit x86 GUI test runner.
My current workaround is to create a console app, copy the code out of the test, run it and print the output to a debug window, and then paste that output back into my test.
Almost every Assertion method (i.e. Assert.AreEquals) takes a "message" parameter as a third argument.
It is printed only on test failures and it is intended to provide useful information to diagnose a test failure. I think it is exactly what you need.
Hope it helps.
(With apologies for any transcription errors in the code below: I was testing this on a remote computer without copy/paste)
I tested the message parameter as suggested by Manuel.
[Test]
public void LongTest()
{
string s1 = new string('.', 1000);
string s1 = new string('.', 500) + "+" + new string('.', 500);
Assert.That(s1, Is.EqualTo(s2));
}
and got the equivalent result to the one in the question:
Changing the Assert to
Assert.That(s1, Is.EqualTo(s2), s1 + "\r\n\r\n" + s2);
changed the result to
which is possibly less than helpful, especially when the tooltip comes up showing you the entire thing. However, you can right-click on that area in the GUI runner and Copy it, and you do indeed get the whole text copied to the clipboard.

How do I customize wintersmith paginator?

I've been setting up a site with Wintersmith and am loving it for the most part, but I cannot wrap my head around some of the under-the-hood mechanics. I started with the "blog" skeleton that adds the paginator.coffee plugin.
The question requires some details, so up top, what I'm trying to accomplish:
Any files (markdown, html, json metadata) will be picked up either in /contents/article/<file> or /contents/articles/<subdir>/<file>
Output files are at /articles/YYYY/MM/DD/title-slug/
/blog.html lists all articles, paginated.
Files just under /contents (not in articles) are not treated as blog posts. Markdown and JSON metadata are still processed, but no permalinked URLs, not included in blog listings, file/directory structure is more directly copied over.
So, I solved #1 with this suggestion: How can I have articles in Wintersmith not in their own subdirectory? So far, great, and #3 is working -- the paginated listing includes all posts. #4 has not been an issue, it's the default behavior.
On #2 I found this solution: http://andrewphilipclark.com/2013/11/08/removing-the-boilerplate-from-wintersmith-blog-posts/ . As the author mentions, his solution was (sort of) subsequently incorporated into Wintersmith master, so I tried just setting the filenameTemplate accordingly. Unfortunately this applies to all content, not just that under /articles, so the rest of my site gets hosed (breaks #4). So then I tried the author's approach, adding a blogpost.coffee plugin using his code. This generates all the files out of /contents/articles into the correct permalink URLs, however the paginator now for some reason will no longer see files directly under /articles (point #1).
I've tried a lot of permutations and hacking. Tried changing the order of which plugin gets loaded first. Tried having PaginatorPage extend BlogpostPage instead of Page. Tried a lot of things. I finally realize, even after inspecting many of the core classes in Wintersmith source, that I do not understand what is happening.
Specifically, I cannot figure out how contents['articles']._.pages and .directories are set, which seems relevant. Nor do I understand what that underscore is.
Ultimately, Jade/CoffeeScript/Markdown are a great combo for minimizing coding and enhancing clarity except when you want to understand what's happening under the hood and you don't know these languages. It took me a bit to get the basics of Jade and CoffeeScript (Markdown is trivial of course) enough to follow what's happening. When I've had to dig into the wintersmith source, it gets deeper. I confess I'm also a node.js newbie, but I think the big issue here is just a magic framework. It would be helpful, for instance, if some of the core "plugins" were included in the skeleton site as opposed to buried in node_modules, just so curious hackers could see more quickly how things interconnect. More verbose docs would of course be helpful too. It's one thing to understand conceptually content trees, generators, views, templates, etc., but understanding the code flow and relations at runtime? I'm lost.
Any help is appreciated. As I said, I'm loving Wintersmith, just wish I could dispel magic.
Because coffee script is rubbish, this is extremely hard to do. However, if you want to, you can destroy the paginator.coffee and replace it with a simple javascript script that does a similar thing:
module.exports = function (env, callback) {
function Page() {
var rtn = new env.plugins.Page();
rtn.getFilename = function() {
return 'index.html';
},
rtn.getView = function() {
return function(env, locals, contents, templates, callback) {
var error = null;
var context = {};
env.utils.extend(context, locals);
var buffer = new Buffer(templates['index.jade'].fn(context));
callback(error, buffer);
};
};
return rtn;
};
/** Generates a custom index page */
function gen(contents, callback) {
var p = Page();
var pages = {'index.page': p};
var error = null;
callback(error, pages);
};
env.registerGenerator('magic', gen);
callback();
};
Notice that due to 'coffee script magic', there are a number of hoops to jump through here, such as making sure you return a buffer from getView(), and 'manually' overriding rather than using the obscure coffee script extension semantics.
Wintersmith is extremely picky about how it handles these functions. If callbacks are not invoked, for the returned value is not a Stream or Buffer, generated files will appear in the content summary, but not be rendered to disk during a build. Enable verbose logging and check of 'skipping foo' messages to detect this.

ICU custom transliteration

I am looking to utilize the ICU library for transliteration, but I would like to provide a custom transliteration file for a set of specific custom transliterations, to be incorporated into the ICU core at compile time for use in binary form elsewhere. I am working with the source of ICU 4.2 for compatibility reasons.
As I understand it, from the ICU Data page of their website, one way of going about this is to create the file trnslocal.mk within ICUHOME/source/data/translit/ , and within this file have the single line TRANSLIT_SOURCE_LOCAL=custom.txt.
For the custom.txt file itself, I used the following format, based on the master file root.txt:
custom{
RuleBasedTransliteratorIDs {
Kanji-Romaji {
file {
resource:process(transliterator){"custom/Kanji_Romaji.txt"}
direction{"FORWARD"}
}
}
}
TransliteratorNamePattern {
// Format for the display name of a Transliterator.
// This is the language-neutral form of this resource.
"{0,choice,0#|1#{1}|2#{1}-{2}}" // Display name
}
// Transliterator display names
// This is the English form of this resource.
"%Translit%Hex" { "%Translit%Hex" }
"%Translit%UnicodeName" { "%Translit%UnicodeName" }
"%Translit%UnicodeChar" { "%Translit%UnicodeChar" }
TransliterateLATIN{
"",
""
}
}
I then store within the directory custom the file Kanji_Romaji.txt, as found here. Because it uses > instead of the → I have seen in other files, I converted each entry appropriately, so they now look like:
丁 → Tei ;
七 → Shichi ;
When I compile the ICU project, I am presented with no errors.
When I attempt to utilize this custom transliterator within a testfile, however (a testfile that works fine with the in-built transliterators), I am met with the error error: 65569:U_INVALID_ID.
I am using the following code to construct the transliterator and output the error:
UErrorCode status = U_ZERO_ERROR;
Transliterator *K_R = Transliterator::createInstance("Kanji-Romaji", UTRANS_FORWARD, status);
if (U_FAILURE(status))
{
std::cout << "error: " << status << ":" << u_errorName(status) << std::endl;
return 0;
}
Additionally, a loop through to Transliterator::countAvailableIDs() and Transliterator::getAvailableID(i) does not list my custom transliteration. I remember reading with regard to custom converters that they must be registered within /source/data/mappings/convrtrs.txt . Is there a similar file for transliterators?
It seems that my custom transliterator is either not being built into the appropriate packages (though there are no compile errors), is improperly formatted, or somehow not being registered for use. Incidentally, I am aware of the RuleBasedTransliterator route at runtime, but I would prefer to be able to compile the custom transliterations for use in any produced binary.
Let me know if any additional clarification is necessary. I know there is at least one ICU programmer on here, who has been quite helpful in other posts I have written and seen elsewhere as well. I would appreciate any help I can find. Thank you in advance!
Transliterators are sourced from CLDR - you could add your transliterator to CLDR (the crosswire directory contains it in XML format in the cldr/ directory) and rebuild ICU data. ICU doesn't have a simple mechanism for adding transliterators as you are trying to do. What I would do is forget about trnslocal.mk or custom.txt as you don't need to add any files, and simply modify root.txt - you might file a bug if you have a suggested improvement.