fill got table for static linking
This commit is contained in:
		
							parent
							
								
									b9aeac0a64
								
							
						
					
					
						commit
						d63ec6f20d
					
				
					 3 changed files with 54 additions and 0 deletions
				
			
		
							
								
								
									
										9
									
								
								libtcc.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								libtcc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -372,6 +372,15 @@ ST_FUNC void *section_ptr_add(Section *sec, unsigned long size)
 | 
			
		|||
    return sec->data + offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* reserve at least 'size' bytes from section start */
 | 
			
		||||
ST_FUNC void section_reserve(Section *sec, unsigned long size)
 | 
			
		||||
{
 | 
			
		||||
    if (size > sec->data_allocated)
 | 
			
		||||
        section_realloc(sec, size);
 | 
			
		||||
    if (size > sec->data_offset)
 | 
			
		||||
        sec->data_offset = size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* return a reference to a section, and create it if it does not
 | 
			
		||||
   exists */
 | 
			
		||||
ST_FUNC Section *find_section(TCCState *s1, const char *name)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								tcc.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								tcc.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -900,6 +900,7 @@ ST_FUNC void add_char(CString *cstr, int c);
 | 
			
		|||
ST_FUNC Section *new_section(TCCState *s1, const char *name, int sh_type, int sh_flags);
 | 
			
		||||
ST_FUNC void section_realloc(Section *sec, unsigned long new_size);
 | 
			
		||||
ST_FUNC void *section_ptr_add(Section *sec, unsigned long size);
 | 
			
		||||
ST_FUNC void section_reserve(Section *sec, unsigned long size);
 | 
			
		||||
ST_FUNC Section *find_section(TCCState *s1, const char *name);
 | 
			
		||||
 | 
			
		||||
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, unsigned long value, unsigned long size, int can_add_underscore);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										44
									
								
								tccelf.c
									
										
									
									
									
								
							
							
						
						
									
										44
									
								
								tccelf.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1365,6 +1365,48 @@ void patch_dynsym_undef(TCCState *s1, Section *s)
 | 
			
		|||
#define	EXTRA_RELITEMS	9
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
ST_FUNC void fill_got_entry(TCCState *s1, ElfW_Rel *rel)
 | 
			
		||||
{
 | 
			
		||||
	int sym_index = ELFW(R_SYM) (rel->r_info);
 | 
			
		||||
	ElfW(Sym) *sym = &((ElfW(Sym) *) symtab_section->data)[sym_index];
 | 
			
		||||
	unsigned long offset;
 | 
			
		||||
 | 
			
		||||
	if (sym_index >= s1->nb_got_offsets)
 | 
			
		||||
		return;
 | 
			
		||||
	offset = s1->got_offsets[sym_index];
 | 
			
		||||
	section_reserve(s1->got, offset + PTR_SIZE);
 | 
			
		||||
	/* only works for x86-64 */
 | 
			
		||||
	put32(s1->got->data + offset, sym->st_value >> 32);
 | 
			
		||||
	put32(s1->got->data + offset, sym->st_value & 0xffffffff);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ST_FUNC void fill_got(TCCState *s1)
 | 
			
		||||
{
 | 
			
		||||
	Section *s;
 | 
			
		||||
	ElfW_Rel *rel, *rel_end;
 | 
			
		||||
	int i;
 | 
			
		||||
 | 
			
		||||
	for(i = 1; i < s1->nb_sections; i++) {
 | 
			
		||||
		s = s1->sections[i];
 | 
			
		||||
		if (s->sh_type != SHT_RELX)
 | 
			
		||||
			continue;
 | 
			
		||||
		/* no need to handle got relocations */
 | 
			
		||||
		if (s->link != symtab_section)
 | 
			
		||||
			continue;
 | 
			
		||||
		rel_end = (ElfW_Rel *) (s->data + s->data_offset);
 | 
			
		||||
		for(rel = (ElfW_Rel *) s->data; rel < rel_end; rel++) {
 | 
			
		||||
			switch (ELFW(R_TYPE) (rel->r_info)) {
 | 
			
		||||
			case R_X86_64_GOT32:
 | 
			
		||||
			case R_X86_64_GOTPCREL:
 | 
			
		||||
			case R_X86_64_PLT32:
 | 
			
		||||
				fill_got_entry(s1, rel);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* output an ELF file */
 | 
			
		||||
/* XXX: suppress unneeded sections */
 | 
			
		||||
static int elf_output_file(TCCState *s1, const char *filename)
 | 
			
		||||
| 
						 | 
				
			
			@ -1985,6 +2027,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
 | 
			
		|||
        else
 | 
			
		||||
            ehdr.e_entry = text_section->sh_addr; /* XXX: is it correct ? */
 | 
			
		||||
    }
 | 
			
		||||
    if (file_type == TCC_OUTPUT_EXE && s1->static_link)
 | 
			
		||||
        fill_got(s1);
 | 
			
		||||
 | 
			
		||||
    /* write elf file */
 | 
			
		||||
    if (file_type == TCC_OUTPUT_OBJ)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue