reloc.Sym.Attr |= sym.AttrReachable | sym.AttrNotInSymbolTable
syms = append(syms, reloc.Sym)
empty = false
- // LLVM doesn't support base address entries. Strip them out so LLDB and dsymutil don't get confused.
- if ctxt.HeadType == objabi.Hdarwin {
- removeLocationListBaseAddress(ctxt, fn, reloc.Sym)
- }
// One location list entry per function, but many relocations to it. Don't duplicate.
break
}
return syms
}
-func removeLocationListBaseAddress(ctxt *Link, info, list *sym.Symbol) {
- // The list symbol contains multiple lists, but they're all for the
- // same function, and it's not empty.
- fn := list.R[0].Sym
-
- // Discard the relocations for the base address entries.
- list.R = list.R[:0]
-
- // Add relocations for each location entry's start and end addresses,
- // so that the base address entries aren't necessary.
- // We could remove them entirely, but that's more work for a relatively
- // small size win. If dsymutil runs it'll throw them away anyway.
-
- // relocate adds a CU-relative relocation to fn+addr at offset.
- relocate := func(addr uint64, offset int) {
- list.R = append(list.R, sym.Reloc{
- Off: int32(offset),
- Siz: uint8(ctxt.Arch.PtrSize),
- Type: objabi.R_ADDRCUOFF,
- Add: int64(addr),
- Sym: fn,
- })
- }
-
- for i := 0; i < len(list.P); {
- first := readPtr(ctxt, list.P[i:])
- second := readPtr(ctxt, list.P[i+ctxt.Arch.PtrSize:])
-
- if first == 0 ||
- first == ^uint64(0) ||
- (ctxt.Arch.PtrSize == 4 && first == uint64(^uint32(0))) {
- // Base address selection entry or end of list. Ignore.
- i += ctxt.Arch.PtrSize * 2
- continue
- }
-
- relocate(first, i)
- relocate(second, i+ctxt.Arch.PtrSize)
-
- // Skip past the actual location.
- i += ctxt.Arch.PtrSize * 2
- i += 2 + int(ctxt.Arch.ByteOrder.Uint16(list.P[i:]))
- }
-
- // Rewrite the DIE's relocations to point to the first location entry,
- // not the now-useless base address selection entry.
- for i := range info.R {
- r := &info.R[i]
- if r.Sym != list {
- continue
- }
- r.Add += int64(2 * ctxt.Arch.PtrSize)
- }
-}
-
-// Read a pointer-sized uint from the beginning of buf.
-func readPtr(ctxt *Link, buf []byte) uint64 {
- switch ctxt.Arch.PtrSize {
- case 4:
- return uint64(ctxt.Arch.ByteOrder.Uint32(buf))
- case 8:
- return ctxt.Arch.ByteOrder.Uint64(buf)
- default:
- panic("unexpected pointer size")
- }
-}
-
/*
* Elf.
*/