Tenho uma grande base de código C, com >100 binários, >3000 arquivos e >30 bibliotecas. Há muito código morto que foi acumulado e estou procurando maneiras de identificar e remover esse código. O código é simples - sem macros complexas e (muito pouco) código gerado automaticamente (lex/bison/...).
Para identificar código morto "estático" (e variáveis), o gcc faz um bom trabalho (usar -Wunused-*
opções identifica todas as variáveis estáticas não utilizadas, funções estáticas, ...). Meu desafio é com funções e variáveis globais não estáticas (e a base de código tem muitas delas!)
Tenho muita experiência usando 'nm' em todos os arquivos de objetos, praticamente criei uma lista de todos os símbolos globais definidos (tipos 'T', 'D' e 'B' para código, dados e não inicializados). Então removi todos os símbolos 'U'. Esse processo identificou todos os globais não referenciados. Neste ponto, tenho que tornar manualmente cada símbolo estático, compilar com gcc -Werror -Wunused
e ver se ele gera algum erro.
# Omitting some details for brevity.
nm --undefined-only lib1.a lib2.a ... obj1 obj2.o obj3.o | sort > refs.txt
nm --extern-only --defined-only lib1.a lib2.a ... obj1 obj2.o obj3.o | sort > defs.txt
join -12 -23 -v2 refs.txt defs.txt
Minha pergunta - é possível usar "nm" (ou outra ferramenta de análise de objetos como objdump
) para identificar quais símbolos globais no arquivo de objeto também são usados dentro do mesmo objeto. Isso acelerará a eliminação de código morto separando o código morto na função global das funções globais que são realmente usadas (mas podem se tornar estáticas).
Alternativamente, existe alguma outra ferramenta existente que faça o trabalho?