symbols for exception handling

mips16 has some unusual requirements for label symbols in .s.

I think that arm thumb has the same issue but have not located yet how this is handled.

When you have a label of an instruction in mips16, when you reference the label, the linker
adds a 1 to the address. When you call an odd numbered address, the procesor switches to mips16 mode and when you call an even numbered address it switches to mips32 mode.

This causes some problems in the exception tables.

Basically, labels that are not landing pad symbols that are inserted for exception handling
and dwarf purposes, must declared :

$mysym = .

as opposed to:


Has this problem of making this distinction already been solved in llvm and if so, how is this done?



I'm working on a patch for this problem for mips16; unfortunately it's a target independent patch.

I'm not sure the best nomenclature for this.

In the gcc mips16 patch they call "xxx=." a debug label.
The other terminology they use is byte pointer vs ISA-encoded address (ISA-encoded meaning this one bit in the case of mips16 ISA).

I'm planning to add a virtual method called EmitDebugLabel to MCStreamer
which just calls method EmitLabel.

Because of some luck, for exception handling at least, I really only need to EmitDebugLabel for eh_func_beginXX.

The other entries in the exception table are all a-b, except for eh_func_beginXX, the 1 bits will cancel each other out. I don't know if this is sufficient for actual dwarf info for debugging; i have not thought through this yet.

The real solution that gcc uses is to distinguish these two kinds of labels everywhere.

I thought of a simpler way to do this which is no more of a hack than the way labels are noramally output.

Create an EmitDebugLabel and then in MCAsminfo, add another variable for the suffix for debug labels which can by default be just ":". Then for Mips I can change it to "=."

My patch seems to work. I'm passing all the mips16 exception handling tests from test-suite.

Unfortunately I touched a lot of target independent code so I'll have to get this patch reviewed. I will test with all Mips flavors and try with the x86 compiler this weekend.

I basically just created an EmitDebugLabel method in MCStreamer and all derived classes.

I added a new field to McAsmino for debug label suffix and made it ":" by default but for Mips I override it to be "=.".

In the dwarf emitter, you can EmitDebugLabel in place of EmitLabel.
For non mips targets, the two functions are the same.

I only call it right now for eh_func_beginXX right now because that is all you need to "right" for exception handling. I may have to go through the rest of the dwarf emitter and add more to get all the dwarf to work for mips16.

In principle, on the landing pad addresses in the table should be real mips16 isa addresses and the rest should be debug labels. That is how gcc mips16 does it.

Can't you use $mysym +/- 1 in the landing pad reference to work this


Hi Joerg,

Interesting idea.The landing pad reference is correct but all the other ones are off by one but the same idea applies.

For the exception handling table I get lucky because all the label addresses that are off by one, except for eh_func begin, end up being subtracted from one another and the extra '1' cancels out.

However, I'm not sure what the ramifications are in the dwarf tables.

I'm just going by the original email discussions on this mips16 c++ handling from gcc that I found. This whole topic was discussed at length. If I follow the abi convention established there, then everything else will work.. gdb, exception library, etc.

In any case, I need to make changes to mcstreamer and that is a class that is dervied from in several places.

I can't put "if inMips16()" in mcstreamer. How would you suggest I handle the data abstraction so that I can change mcstreamer for my use and minimally effect others without polluting the namespace of mcstreamer with "mips16"?

I have a patch I will submit today for review, though I'm not at all wedded to this idea, it's just something that is not unreasonable and I was able to get to work and solve my problem in a few hours.

I just had to introduce the notion of EmitDebugSymbol to mcstreamer.
Everything was very clean; the only issues was having to add EmitDDebugLabel as a synonym for EmitLabel in all the derived classes except for the assembler emitter, though I will need to make fixes later to at least the elf emitter to accommodate the direct object emitter.

That part about having to touch those other derived classes seemed wrong to me but I didn't think of a better solution.