📄 cofflwlv.c
字号:
return( ORL_RELOC_TYPE_REL_32_ADJ4 );
case IMAGE_REL_AMD64_REL32_5:
return( ORL_RELOC_TYPE_REL_32_ADJ5 );
default:
return( ORL_RELOC_TYPE_NONE );
}
} else if( coff_file_hnd->machine_type == ORL_MACHINE_TYPE_PPC601 ) {
switch( coff_type & IMAGE_REL_PPC_TYPEMASK ) {
case IMAGE_REL_PPC_ABSOLUTE: // NOP
return( ORL_RELOC_TYPE_ABSOLUTE );
case IMAGE_REL_PPC_ADDR64: // 64-bit address
return( ORL_RELOC_TYPE_WORD_64 );
case IMAGE_REL_PPC_ADDR32: // 32-bit address
return( ORL_RELOC_TYPE_WORD_32 );
case IMAGE_REL_PPC_ADDR24: // 26-bit address, shifted left 2 (branch absolute)
return( ORL_RELOC_TYPE_WORD_24 );
case IMAGE_REL_PPC_ADDR16: // 16-bit address
return( ORL_RELOC_TYPE_WORD_16 );
case IMAGE_REL_PPC_ADDR14: // 16-bit address, shifted left 2 (load doubleword)
return( ORL_RELOC_TYPE_WORD_14);
case IMAGE_REL_PPC_REL24: // 26-bit PC-relative offset, shifted left 2 (branch relative)
return( ORL_RELOC_TYPE_REL_24 );
case IMAGE_REL_PPC_REL14: // 16-bit PC-relative offset, shifted left 2 (br cond relative)
return( ORL_RELOC_TYPE_REL_14 );
case IMAGE_REL_PPC_TOCREL16: // 16-bit offset from TOC base
if( coff_type & IMAGE_REL_PPC_TOCDEFN ) {
return( ORL_RELOC_TYPE_TOCVREL_16 );
} else {
return( ORL_RELOC_TYPE_TOCREL_16 );
}
case IMAGE_REL_PPC_TOCREL14: // 14-bit offset from TOC base, shifted left 2 (load doubleword)
if( coff_type & IMAGE_REL_PPC_TOCDEFN ) {
return( ORL_RELOC_TYPE_TOCVREL_14 );
} else {
return( ORL_RELOC_TYPE_TOCREL_14 );
}
case IMAGE_REL_PPC_SECREL:
return( ORL_RELOC_TYPE_SEC_REL );
case IMAGE_REL_PPC_SECTION:
return( ORL_RELOC_TYPE_SEGMENT );
case IMAGE_REL_PPC_ADDR32NB: // 32-bit addr w/o image base
return( ORL_RELOC_TYPE_WORD_32_NB );
case IMAGE_REL_PPC_IFGLUE: // Substitute TOC restore instruction iff symbol is glue code
return( ORL_RELOC_TYPE_IFGLUE );
case IMAGE_REL_PPC_IMGLUE:
return( ORL_RELOC_TYPE_IMGLUE );
default:
return( ORL_RELOC_TYPE_NONE );
}
} else if( coff_file_hnd->machine_type == ORL_MACHINE_TYPE_R3000
|| coff_file_hnd->machine_type == ORL_MACHINE_TYPE_R4000 ) {
switch( coff_type ) {
case IMAGE_REL_MIPS_ABSOLUTE: // NOP
return( ORL_RELOC_TYPE_ABSOLUTE );
case IMAGE_REL_MIPS_REFWORD: // 32-bit address
return( ORL_RELOC_TYPE_WORD_32 );
case IMAGE_REL_MIPS_JMPADDR: // 26-bit absolute address (j/jal)
return( ORL_RELOC_TYPE_WORD_26 );
case IMAGE_REL_MIPS_REFHI:
return( ORL_RELOC_TYPE_HALF_HI );
case IMAGE_REL_MIPS_REFLO:
return( ORL_RELOC_TYPE_HALF_LO );
case IMAGE_REL_MIPS_PAIR:
return( ORL_RELOC_TYPE_PAIR );
case IMAGE_REL_MIPS_GPREL: // 16-bit offset from GP register
case IMAGE_REL_MIPS_LITERAL:
return( ORL_RELOC_TYPE_TOCREL_16 );
case IMAGE_REL_MIPS_SECREL:
return( ORL_RELOC_TYPE_SEC_REL );
case IMAGE_REL_MIPS_SECTION:
return( ORL_RELOC_TYPE_SEGMENT );
case IMAGE_REL_MIPS_REFWORDNB: // 32-bit addr w/o image base
return( ORL_RELOC_TYPE_WORD_32_NB );
default:
return( ORL_RELOC_TYPE_NONE );
}
}
return( 0 );
}
orl_return CoffCreateRelocs( coff_sec_handle orig_sec, coff_sec_handle reloc_sec )
{
orl_return return_val;
unsigned num_relocs;
int loop;
coff_reloc ORLUNALIGNED *rel;
orl_reloc * o_rel;
orl_reloc * prev_rel;
if( reloc_sec->coff_file_hnd->symbol_handles == NULL ) {
return_val = CoffCreateSymbolHandles( reloc_sec->coff_file_hnd );
if( return_val != ORL_OKAY ) return( return_val );
}
num_relocs = reloc_sec->size / sizeof( coff_reloc );
reloc_sec->assoc.reloc.num_relocs = num_relocs;
reloc_sec->assoc.reloc.relocs = (orl_reloc *) _ClientSecAlloc( reloc_sec, sizeof( orl_reloc ) * num_relocs );
if( reloc_sec->assoc.reloc.relocs == NULL ) return( ORL_OUT_OF_MEMORY );
rel = (coff_reloc *) reloc_sec->contents;
o_rel = (orl_reloc *) reloc_sec->assoc.reloc.relocs;
for( loop = 0; loop < num_relocs; loop++ ) {
o_rel->section = (orl_sec_handle) orig_sec;
if( reloc_sec->coff_file_hnd->machine_type == ORL_MACHINE_TYPE_ALPHA
&& rel->type == IMAGE_REL_ALPHA_MATCH ) {
o_rel->type = ORL_RELOC_TYPE_HALF_LO;
prev_rel = o_rel - 1;
o_rel->symbol = prev_rel->symbol;
o_rel->offset = prev_rel->offset + rel->sym_tab_index;
} else {
o_rel->type = CoffConvertRelocType( reloc_sec->coff_file_hnd, rel->type );
if( o_rel->type == ORL_RELOC_TYPE_PAIR ) {
o_rel->symbol = NULL;
} else {
o_rel->symbol = (orl_symbol_handle) &(reloc_sec->coff_file_hnd->symbol_handles[rel->sym_tab_index]);
}
o_rel->offset = rel->offset - orig_sec->hdr->offset;
}
o_rel->addend = 0;
o_rel->frame = NULL;
rel++;
o_rel++;
}
return( ORL_OKAY );
}
orl_linnum * CoffConvertLines( coff_sec_handle hdl, orl_table_index numlines )
/****************************************************************************/
{
orl_linnum ORLUNALIGNED * currline;
coff_line_num ORLUNALIGNED *coffline;
orl_linnum ORLUNALIGNED * linestart;
coff_file_handle fhdl;
unsigned_32 linebase;
coff_symbol_handle sym;
coff_sym_bfef * csym;
unsigned_32 offset;
fhdl = hdl->coff_file_hnd;
if( fhdl->symbol_handles == NULL ) {
if( CoffCreateSymbolHandles( fhdl ) != ORL_OKAY ) return NULL;
}
coffline = (coff_line_num *) (hdl->hdr->lineno_ptr - fhdl->initial_size
+ fhdl->rest_of_file_buffer);
currline = (orl_linnum *) coffline;
if( hdl->relocs_done ) return (orl_linnum *)currline;
linestart = currline;
linebase = 0;
while( numlines > 0 ) {
if( coffline->line_number == 0 ) {
sym = &fhdl->symbol_handles[coffline->symbol_table_index];
coffline->RVA = sym->symbol->value;
if( sym->has_bf ) {
csym = (coff_sym_bfef *)(sym->symbol + sym->symbol->num_aux +2);
linebase = csym->linenum;
}
}
offset = coffline->RVA;
currline->linnum = coffline->line_number + linebase;
currline->off = offset;
coffline++;
currline++;
numlines--;
}
hdl->relocs_done = COFF_TRUE;
return (orl_linnum *) linestart;
}
static size_t strncspn( char *s, char *charset, int len) {
char chartable[32];
int i;
unsigned char ch;
memset(chartable, 0, sizeof chartable);
for( ; *charset != 0; charset++ ) {
ch = *charset;
chartable[ch / 8] |= 1 << ch % 8;
}
for (i = 0; i < len; i++) {
ch = s[i];
if( chartable[ch/8] & (1 << ch % 8) ) {
break;
}
}
return i;
}
static char *pstrncspn( char *s, char *charset, int *len ) {
int l = strncspn(s, charset, *len);
*len -= l;
return s + l;
}
static void EatWhite( char **contents, int *len )
/***********************************************/
{
char ch = **contents;
while( (ch == ' ' || ch == '\t' || ch == '=' || ch == ',') && *len > 0 ) {
(*len)--;
*contents += 1;
ch = **contents;
}
}
static orl_return ParseExport( char **contents, int *len,
orl_note_callbacks *cb, void *cookie )
/********************************************************************/
{
char * arg;
int l;
l = strncspn( *contents, ", \t", *len );
arg = alloca((l+1));
memcpy(arg, *contents, l); arg[l] = 0;
*len -= l;
*contents += l;
return cb->export_fn( arg, cookie );
}
static orl_return ParseDefLibEntry( char **contents, int *len,
orl_return (*deflibentry_fn)( char *, void * ), void *cookie )
/************************************************************************/
{
char * arg;
int l;
orl_return retval;
for(;;) {
l = strncspn( *contents, ", \t", *len );
arg = alloca(l+1);
memcpy(arg, *contents, l); arg[l] = 0;
*len -= l;
*contents += l;
retval = deflibentry_fn( arg, cookie );
if( retval != ORL_OKAY || **contents != ',' ) break;
(*contents)++;
}
return retval;
}
orl_return CoffParseDrectve( char *contents, int len, orl_note_callbacks *cb,
void *cookie)
/*******************************************************************/
{
char * cmd;
EatWhite( &contents, &len );
while( len > 0 ) {
if( *contents != '-' ) break; // - should be start of token
contents++; len--;
cmd = contents;
contents = pstrncspn( contents, ":", &len);
if( contents == NULL ) break;
contents++; len--;
if( memicmp( cmd, "export", 6 ) == 0 ) {
if( ParseExport( &contents, &len, cb, cookie ) != ORL_OKAY ) break;
} else if( memicmp( cmd, "defaultlib", 10 ) == 0 ) {
if( ParseDefLibEntry( &contents, &len, cb->deflib_fn, cookie )
!= ORL_OKAY ) break;
} else if( memicmp( cmd, "entry", 5 ) == 0 ) {
if( ParseDefLibEntry( &contents, &len, cb->entry_fn, cookie )
!= ORL_OKAY ) break;
}
EatWhite( &contents, &len );
}
return( ORL_OKAY );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -