void elfrelocsect(Section *sect, Sym *first) { Sym *sym, *rs; int32 eaddr; Reloc *r; int64 add; // If main section is SHT_NOBITS, nothing to relocate. // Also nothing to relocate in .shstrtab. if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen) return; if(strcmp(sect->name, ".shstrtab") == 0) return; sect->reloff = cpos(); for(sym = first; sym != nil; sym = sym->next) { if(!sym->reachable) continue; if(sym->value >= sect->vaddr) break; } eaddr = sect->vaddr + sect->len; for(; sym != nil; sym = sym->next) { if(!sym->reachable) continue; if(sym->value >= eaddr) break; cursym = sym; for(r = sym->r; r < sym->r+sym->nr; r++) { // Ignore relocations handled by reloc already. switch(r->type) { case D_SIZE: continue; case D_ADDR: case D_PCREL: if(r->sym->type == SCONST) continue; break; } add = r->add; rs = r->sym; while(rs->outer != nil) { add += rs->value - rs->outer->value; rs = rs->outer; } if(rs->elfsym == 0) diag("reloc %d to non-elf symbol %s (rs=%s) %d", r->type, r->sym->name, rs->name, rs->type); if(elfreloc1(r, sym->value - sect->vaddr + r->off, rs->elfsym, add) < 0) diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name); } } sect->rellen = cpos() - sect->reloff; }
void elfrelocsect(Section *sect, Sym *first) { Sym *sym; int32 eaddr; Reloc *r; // If main section is SHT_NOBITS, nothing to relocate. // Also nothing to relocate in .shstrtab. if(sect->vaddr >= sect->seg->vaddr + sect->seg->filelen) return; if(strcmp(sect->name, ".shstrtab") == 0) return; sect->reloff = cpos(); for(sym = first; sym != nil; sym = sym->next) { if(!sym->reachable) continue; if(sym->value >= sect->vaddr) break; } eaddr = sect->vaddr + sect->len; for(; sym != nil; sym = sym->next) { if(!sym->reachable) continue; if(sym->value >= eaddr) break; cursym = sym; for(r = sym->r; r < sym->r+sym->nr; r++) { if(r->done) continue; if(r->xsym == nil) { diag("missing xsym in relocation"); continue; } if(r->xsym->elfsym == 0) diag("reloc %d to non-elf symbol %s (outer=%s) %d", r->type, r->sym->name, r->xsym->name, r->sym->type); if(elfreloc1(r, sym->value+r->off - sect->vaddr) < 0) diag("unsupported obj reloc %d/%d to %s", r->type, r->siz, r->sym->name); } } sect->rellen = cpos() - sect->reloff; }