3b45b8cbf1
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@18896 a1c6a512-1295-4272-9138-f99709370657
436 lines
14 KiB
C
436 lines
14 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2008 by Jin Le
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
|
|
|
|
/*
|
|
* dl_analyser.c ONDA VX767 DL file analyser
|
|
*
|
|
* Copyright (C) 2008 - JinLe
|
|
*
|
|
* This is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with ; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301 USA
|
|
|
|
The DL file can not find any entry point,
|
|
so I think it just a dynamic library
|
|
not executable.
|
|
|
|
IN THE FILE
|
|
+--------------------------
|
|
+ block_header_t
|
|
+--------------------------
|
|
+ block_impt_header_t
|
|
+--------------------------
|
|
+ block_expt_header_t
|
|
+--------------------------
|
|
+ block_raw_header_t
|
|
+--------------------------
|
|
+ import symbol
|
|
+--------------------------
|
|
+ export symbol
|
|
+--------------------------
|
|
+ padding
|
|
+-------------------------- <-----(raw->offset)
|
|
+
|
|
+ raw code seg
|
|
+
|
|
+--------------------------
|
|
+
|
|
+ inited mem seg
|
|
+
|
|
+-------------------------- <-----(raw->offset + raw->size)(bss start)
|
|
|
|
IN THE MEMORY
|
|
+-------------------------- <-----(raw->mem2)
|
|
+
|
|
+ code seg
|
|
+
|
|
+--------------------------
|
|
+
|
|
+ inited mem seg
|
|
+
|
|
+-------------------------- <-----(raw->mem2 + raw->size)(bss start)
|
|
+
|
|
+ BSS(Not in file)
|
|
+
|
|
+-------------------------- <-----(raw->mem2 + raw->memsize)(bss end)
|
|
|
|
HOW TO disassemble (Ex: VX767_V1.0.dl)
|
|
|
|
STEP 1:
|
|
./dl_analyser VX767_V1.0.dl
|
|
|
|
=======================HEADER=====================
|
|
File magic: CCDL
|
|
File Type : 0x00010000
|
|
Offset : 0x00020001
|
|
Size : 0x00000004
|
|
BuildDate : 2008/03/26 09:59:19
|
|
PaddindSum: 0x0
|
|
=====================IMPT HEADER==================
|
|
Header magic : IMPT
|
|
Header Type : 0x00000008
|
|
Offset : 0x000000a0
|
|
Size : 0x0000007c
|
|
PaddindSum : 0x0
|
|
=====================EXPT HEADER==================
|
|
Header magic : EXPT
|
|
Header Type : 0x00000009
|
|
Offset : 0x00000120
|
|
Size : 0x00000108
|
|
PaddindSum : 0x0
|
|
=====================RAWD HEADER==================
|
|
Header magic : RAWD
|
|
Header Type : 0x00000001
|
|
Offset : 0x00000230
|
|
Size : 0x000058a0
|
|
Paddind1 : 0x0
|
|
BSS Clear Code : 0x80f82714 start at file 0x2944
|
|
mem_place_start : 0x80f80000 start at file 0x230
|
|
memsize : 0x5a58
|
|
mem_end(BSS end): 0x80f85a58
|
|
Paddind2Sum : 0x0
|
|
=====================IMPORT SYMBOL==================
|
|
number symbols : 0x4
|
|
PaddindSum : 0x0
|
|
Sym[00] offset 0x0000 padding 0x0 flag 0x20000 address 0x80f82750 name: printf
|
|
Sym[01] offset 0x0008 padding 0x0 flag 0x20000 address 0x80f82758 name: udelay
|
|
Sym[02] offset 0x0010 padding 0x0 flag 0x20000 address 0x80f82760 name: delay_ms
|
|
Sym[03] offset 0x001c padding 0x0 flag 0x20000 address 0x80f82768 name: get_rgb_lcd_buf
|
|
=====================EXPORT SYMBOL==================
|
|
number symbols : 0x7
|
|
PaddindSum : 0x0
|
|
Sym[00] offset 0x0000 padding 0x0 flag 0x20000 address 0x80f826dc name: init_lcd_register
|
|
Sym[01] offset 0x0014 padding 0x0 flag 0x20000 address 0x80f80160 name: get_ccpmp_config
|
|
Sym[02] offset 0x0028 padding 0x0 flag 0x20000 address 0x80f82690 name: get_bklight_config
|
|
Sym[03] offset 0x003c padding 0x0 flag 0x20000 address 0x80f81120 name: init_lcd_gpio
|
|
Sym[04] offset 0x004c padding 0x0 flag 0x20000 address 0x80f804d0 name: rgb_user_init
|
|
Sym[05] offset 0x005c padding 0x0 flag 0x20000 address 0x80f806a4 name: get_rgb_frame_buf
|
|
Sym[06] offset 0x0070 padding 0x0 flag 0x20000 address 0x80f8269c name: lcd_set_direction_mode
|
|
|
|
STEP 2:
|
|
mips-linux-objdump -bbinary -mmips -D VX767_V1.0.dl > 767.as
|
|
|
|
STEP 3:
|
|
for function lcd_set_direction_mode(address 0x80f8269c)
|
|
we translate that address into 'file address'
|
|
file address = 0x80f8269c - 0x80f80000 + 0x230 = 0x28CC
|
|
|
|
STEP 4:
|
|
Find code in 767.as use this 'file address'
|
|
|
|
2008.10.20 6:23PM
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
|
|
/*******************************HEADER*****************************/
|
|
typedef struct
|
|
{
|
|
char magic[4];
|
|
int type;
|
|
int offset;
|
|
int size;
|
|
unsigned char date[7];
|
|
unsigned char padding[9];
|
|
}block_header_t;
|
|
|
|
typedef struct
|
|
{
|
|
char magic[4];
|
|
int type;
|
|
int offset;
|
|
int size;
|
|
int padding[4];
|
|
}block_impt_header_t;
|
|
|
|
typedef struct
|
|
{
|
|
char magic[4];
|
|
int type;
|
|
int offset;
|
|
int size;
|
|
int padding[4];
|
|
}block_expt_header_t;
|
|
|
|
typedef struct
|
|
{
|
|
char magic[4];
|
|
int type;
|
|
int offset;
|
|
int size;
|
|
int padding1;
|
|
int mem1;
|
|
int mem2;
|
|
int memsize;
|
|
int padding2[8];
|
|
}block_raw_header_t;
|
|
|
|
/*******************************SYMBOL*****************************/
|
|
typedef struct
|
|
{
|
|
int offset;
|
|
int padding;
|
|
int flag;
|
|
int address;
|
|
char *name;
|
|
}symbol_t;
|
|
|
|
typedef struct
|
|
{
|
|
int numsymbol;
|
|
int padding[3];
|
|
int isimport;
|
|
symbol_t *symbol;
|
|
}import_export_symbol_t;
|
|
|
|
void usage(char *name)
|
|
{
|
|
fprintf(stderr, "Usage: %s [dl file]\n", name);
|
|
}
|
|
|
|
void dump_header(block_header_t *header)
|
|
{
|
|
int tmp;
|
|
fprintf(stderr, "=======================HEADER=====================\n");
|
|
fprintf(stderr, "File magic: %c%c%c%c\n", header->magic[0], header->magic[1], header->magic[2], header->magic[3]);
|
|
fprintf(stderr, "File Type : 0x%08x\n", header->type);
|
|
fprintf(stderr, "Offset : 0x%08x\n", header->offset);
|
|
fprintf(stderr, "Size : 0x%08x\n", header->size);
|
|
fprintf(stderr, "BuildDate : %02x%02x/%02x/%02x %02x:%02x:%02x\n",
|
|
header->date[0], header->date[1],
|
|
header->date[2], header->date[3],
|
|
header->date[4], header->date[5],
|
|
header->date[6]);
|
|
tmp = header->padding[0] + header->padding[1] + header->padding[2] + header->padding[3] + header->padding[4] +
|
|
header->padding[5] + header->padding[6] + header->padding[7] + header->padding[8];
|
|
fprintf(stderr, "PaddindSum: 0x%x\n", tmp);
|
|
}
|
|
|
|
void dump_import_symbol_header(block_impt_header_t *impt)
|
|
{
|
|
int tmp;
|
|
fprintf(stderr, "=====================IMPT HEADER==================\n");
|
|
fprintf(stderr, "Header magic : %c%c%c%c\n", impt->magic[0], impt->magic[1], impt->magic[2], impt->magic[3]);
|
|
fprintf(stderr, "Header Type : 0x%08x\n", impt->type);
|
|
fprintf(stderr, "Offset : 0x%08x\n", impt->offset);
|
|
fprintf(stderr, "Size : 0x%08x\n", impt->size);
|
|
tmp = impt->padding[0] + impt->padding[1] + impt->padding[2] + impt->padding[3];
|
|
fprintf(stderr, "PaddindSum : 0x%x\n", tmp);
|
|
}
|
|
|
|
void dump_export_symbol_header(block_expt_header_t *expt)
|
|
{
|
|
int tmp;
|
|
fprintf(stderr, "=====================EXPT HEADER==================\n");
|
|
fprintf(stderr, "Header magic : %c%c%c%c\n", expt->magic[0], expt->magic[1], expt->magic[2], expt->magic[3]);
|
|
fprintf(stderr, "Header Type : 0x%08x\n", expt->type);
|
|
fprintf(stderr, "Offset : 0x%08x\n", expt->offset);
|
|
fprintf(stderr, "Size : 0x%08x\n", expt->size);
|
|
tmp = expt->padding[0] + expt->padding[1] + expt->padding[2] + expt->padding[3];
|
|
fprintf(stderr, "PaddindSum : 0x%x\n", tmp);
|
|
}
|
|
|
|
void dump_raw_data_header(block_raw_header_t *raw)
|
|
{
|
|
int tmp;
|
|
fprintf(stderr, "=====================RAWD HEADER==================\n");
|
|
fprintf(stderr, "Header magic : %c%c%c%c\n", raw->magic[0], raw->magic[1], raw->magic[2], raw->magic[3]);
|
|
fprintf(stderr, "Header Type : 0x%08x\n", raw->type);
|
|
fprintf(stderr, "Offset : 0x%08x\n", raw->offset);
|
|
fprintf(stderr, "Size : 0x%08x\n", raw->size);
|
|
fprintf(stderr, "Paddind1 : 0x%x\n", raw->padding1);
|
|
fprintf(stderr, "BSS Clear Code : 0x%x start at file 0x%x\n", raw->mem1, raw->mem1-raw->mem2+raw->offset);
|
|
fprintf(stderr, "mem_start : 0x%x start at file 0x%x\n", raw->mem2, raw->offset);
|
|
fprintf(stderr, "memsize : 0x%x\n", raw->memsize);
|
|
fprintf(stderr, "mem_end(BSS end): 0x%x\n", raw->memsize + raw->mem2);
|
|
tmp = raw->padding2[0] + raw->padding2[1] + raw->padding2[2] + raw->padding2[3] +
|
|
raw->padding2[4] + raw->padding2[5] + raw->padding2[6] + raw->padding2[7];
|
|
fprintf(stderr, "Paddind2Sum : 0x%x\n", tmp);
|
|
}
|
|
|
|
void dump_symbol_table(import_export_symbol_t *sym, char *prefix)
|
|
{
|
|
int tmp;
|
|
int i;
|
|
|
|
fprintf(stderr, "=====================%s==================\n", prefix);
|
|
fprintf(stderr, "number symbols : 0x%x\n", sym->numsymbol);
|
|
tmp = sym->padding[0] + sym->padding[1] + sym->padding[2];
|
|
fprintf(stderr, "PaddindSum : 0x%x\n", tmp);
|
|
for(i=0; i<sym->numsymbol; i++)
|
|
{
|
|
fprintf(stderr, "Sym[%02d] offset 0x%04x padding 0x%x flag 0x%x address 0x%x name: %s\n",
|
|
i, sym->symbol[i].offset, sym->symbol[i].padding,
|
|
sym->symbol[i].flag, sym->symbol[i].address, sym->symbol[i].name);
|
|
}
|
|
}
|
|
|
|
static int read_symbols(int fd, import_export_symbol_t *sym)
|
|
{
|
|
int numbers = sym->numsymbol;
|
|
int i, ret;
|
|
int len = 0, flag = 0;
|
|
char buffer;
|
|
int nametab_offset;
|
|
|
|
if(numbers == 0 || fd < 0)
|
|
return 0;
|
|
/*Read table*/
|
|
sym->symbol = (symbol_t *)malloc(sizeof(symbol_t) * numbers);
|
|
for(i=0; i<numbers; i++)
|
|
{
|
|
/*Offset*/
|
|
if((ret = read(fd, &sym->symbol[i].offset, sizeof(int))) < 0)
|
|
return -1;
|
|
/*Padding*/
|
|
if((ret = read(fd, &sym->symbol[i].padding, sizeof(int))) < 0)
|
|
return -1;
|
|
/*Flag*/
|
|
if((ret = read(fd, &sym->symbol[i].flag, sizeof(int))) < 0)
|
|
return -1;
|
|
/*Address*/
|
|
if((ret = read(fd, &sym->symbol[i].address, sizeof(int))) < 0)
|
|
return -1;
|
|
}
|
|
/*Read name*/
|
|
nametab_offset = lseek(fd, 0, SEEK_CUR);
|
|
for(i=0; i<numbers; i++)
|
|
{
|
|
/*Set seek start*/
|
|
lseek(fd, nametab_offset + sym->symbol[i].offset, SEEK_SET);
|
|
/*get length of name*/
|
|
while(flag != 2)
|
|
{
|
|
if((ret = read(fd, &buffer, sizeof(char))) < 0)
|
|
return -1;
|
|
if(buffer != 0)
|
|
len++;
|
|
else
|
|
flag++;
|
|
}
|
|
if(len == 0)
|
|
break;
|
|
/*Reset seek start*/
|
|
lseek(fd, nametab_offset + sym->symbol[i].offset, SEEK_SET);
|
|
/*Read name*/
|
|
sym->symbol[i].name = (char *)malloc(sizeof(char) * (len+1));
|
|
memset(sym->symbol[i].name, 0, len+1);
|
|
if((ret = read(fd, sym->symbol[i].name, sizeof(char)*len)) < 0)
|
|
return -1;
|
|
flag = len = 0;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
int analyze_dl(int fd)
|
|
{
|
|
int ret = -1;
|
|
block_header_t header;
|
|
block_impt_header_t impt;
|
|
block_expt_header_t expt;
|
|
block_raw_header_t raw;
|
|
import_export_symbol_t isym;
|
|
import_export_symbol_t esym;
|
|
|
|
/*Read Header*/
|
|
if((ret = read(fd, &header, sizeof(block_header_t))) < 0)
|
|
return -1;
|
|
dump_header(&header);
|
|
/*Read Import header*/
|
|
if((ret = read(fd, &impt, sizeof(block_impt_header_t))) < 0)
|
|
return -1;
|
|
dump_import_symbol_header(&impt);
|
|
/*Read Export header*/
|
|
if((ret = read(fd, &expt, sizeof(block_expt_header_t))) < 0)
|
|
return -1;
|
|
dump_export_symbol_header(&expt);
|
|
/*Read Raw data header*/
|
|
if((ret = read(fd, &raw, sizeof(block_raw_header_t))) < 0)
|
|
return -1;
|
|
dump_raw_data_header(&raw);
|
|
|
|
/*read import symbol*/
|
|
lseek(fd, impt.offset, SEEK_SET);
|
|
/*number*/
|
|
if((ret = read(fd, &isym.numsymbol, sizeof(int))) < 0)
|
|
return -1;
|
|
/*padding*/
|
|
if((ret = read(fd, &isym.padding, sizeof(int)*3)) < 0)
|
|
return -1;
|
|
if((ret = read_symbols(fd, &isym)) < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
dump_symbol_table(&isym, "IMPORT SYMBOL");
|
|
|
|
/*read export symbol*/
|
|
lseek(fd, expt.offset, SEEK_SET);
|
|
/*number*/
|
|
if((ret = read(fd, &esym.numsymbol, sizeof(int))) < 0)
|
|
return -1;
|
|
/*padding*/
|
|
if((ret = read(fd, &esym.padding, sizeof(int)*3)) < 0)
|
|
return -1;
|
|
if((ret = read_symbols(fd, &esym)) < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
dump_symbol_table(&esym, "EXPORT SYMBOL");
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int fd = -1;
|
|
int ret = -1;
|
|
|
|
if(argc != 2)
|
|
{
|
|
usage(argv[0]);
|
|
return -1;
|
|
}
|
|
fd = open(argv[1], O_RDONLY);
|
|
if(fd < 0)
|
|
{
|
|
perror("Open");
|
|
return -1;
|
|
}
|
|
ret = analyze_dl(fd);
|
|
return ret;
|
|
}
|