Símbolos fracos na glibc permitem a substituição, mesmo sob vinculação estática.
A saída global é um símbolo strong. Definições adicionais não serão resolvidas e aumentarão os erros de vinculação.
Assim, você pode ser capaz de fornecer seu próprio puts e, exceto uma segunda definição de puts que seja strong, o puts com a maior ocupação de memória (tamanho) será escolhido.
Por que o maior tamanho? Bem, o GCC precisa de algum discriminador, e a maior parte do glibc é estruturada de tal forma que os símbolos públicos são quase universalmente aliados a símbolos privados, o que significa que o tamanho é pequeno (um salto). Isso significa que, se você fornecer sua própria implementação de puts , a menos que você a estruture para alias exatamente da mesma maneira, as probabilidades são de que a implementação seja maior. Para puts , o alias direciona para __IO_puts .
Este é o mecanismo pelo qual a biblioteca padrão fornece implementações de chamadas de biblioteca padrão e permite que você as sobrescreva.