Ejemplo n.º 1
0
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;
}	
Ejemplo n.º 2
0
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;
}